package com.thinking.live.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.alibaba.fastjson.JSONObject;
import com.thinking.live.config.RechargeConfig;
import com.thinking.live.entity.pojo.req.RechargeMoneyReq;
import com.thinking.live.entity.pojo.req.RechargeQueryReq;
import com.thinking.live.entity.pojo.req.RevocationReq;
import com.thinking.live.entity.pojo.resp.RechargeMoneyResp;
import com.thinking.live.entity.pojo.resp.RechargeQueryResp;
import com.thinking.live.entity.pojo.resp.RevocationResp;
import com.thinking.live.service.RechargeMoneyService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class RechargeMoneyServiceImpl implements RechargeMoneyService {

    @Resource
    private RestTemplate restTemplate;

    @Resource
    private RechargeConfig rechargeConfig;

    /**
     * 充值接口
     * @param request
     * @return
     */
    @Override
    public RechargeMoneyResp rechargeMoney(RechargeMoneyReq request) {
        Map<String, Object> map = new HashMap<>();
        map.put("out_trade_num", request.getOutTradeNum());
        map.put("product_id", request.getProductId());
        map.put("mobile", request.getMobile());
        if (ObjectUtil.isNotEmpty(request.getArea())) {
            map.put("area", request.getArea());
        }
        if (ObjectUtil.isNotEmpty(request.getCity())) {
            map.put("city", request.getCity());
        }
        if (ObjectUtil.isNotEmpty(request.getYtype())) {
            map.put("ytype", request.getYtype());
        }
        if (ObjectUtil.isNotEmpty(request.getIdCardNno())) {
            map.put("id_card_no", request.getIdCardNno());
        }
        //map.put("amount", request.getAmount());
        map.put("notify_url", rechargeConfig.getNotifyurl());
        map.put("userid", StrUtil.equals(request.getType(),"huafei")? rechargeConfig.getUserid():rechargeConfig.getUserIdHY());

        log.debug("rechargeConfig中的参数：{}, {}", rechargeConfig.getNotifyurl(),StrUtil.equals(request.getType(),"huafei")? rechargeConfig.getUserid():rechargeConfig.getUserIdHY());

        //生成签名
        String signature = createSignature(map,StrUtil.equals(request.getType(),"huafei")?rechargeConfig.getApikey().replace("T",""):rechargeConfig.getApiKeyHY().replace("T",""));
        log.debug("rechargeMoney方法生成的签名：{}", signature);

        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
        log.debug("初始params：{}", JSONObject.toJSONString(params));
        params.add("out_trade_num", request.getOutTradeNum());
        params.add("product_id", request.getProductId());
        params.add("mobile", request.getMobile());
        //params.add("amount", request.getAmount());
        if (ObjectUtil.isNotEmpty(request.getArea())) {
            params.add("area", request.getArea());
        }
        if (ObjectUtil.isNotEmpty(request.getCity())) {
            params.add("city", request.getCity());
        }
        if (ObjectUtil.isNotEmpty(request.getYtype())) {
            params.add("ytype", request.getYtype());
        }
        if (ObjectUtil.isNotEmpty(request.getIdCardNno())) {
            params.add("id_card_no", request.getIdCardNno());
        }
        params.add("notify_url", rechargeConfig.getNotifyurl());
        params.add("userid", StrUtil.equals(request.getType(),"huafei")? rechargeConfig.getUserid():rechargeConfig.getUserIdHY());
        params.add("sign", signature);
        log.debug("结束params： {}", JSONObject.toJSONString(params));

      //  log.info("开始调用第三方接口！");
        try {
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
            HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers);
            log.info("requestEntity：{}", JSONObject.toJSONString(requestEntity));
            ResponseEntity<RechargeMoneyResp> response = restTemplate.exchange(rechargeConfig.getRechargeurl(), HttpMethod.POST, requestEntity, RechargeMoneyResp.class);
            log.info("第三方接口调用结束！response：{}", JSONObject.toJSONString(response));
            return response.getBody();
        } catch (Exception e) {
            log.error("调用第三方出错：{}", e.getMessage());
            throw new RuntimeException(e);
        }
    }

    /**
     * 撤销订单
     * @return
     */
    @Override
    public RevocationResp revocation(RevocationReq request) {
        Map<String, Object> map = new HashMap<>();
        map.put("out_trade_nums", request.getOutTradeNums());
        map.put("userid", StrUtil.equals(request.getType(),"huafei")? rechargeConfig.getUserid():rechargeConfig.getUserIdHY());
        String signature = createSignature(map,rechargeConfig.getApikey().replace("T",""));

        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
        params.add("out_trade_nums", request.getOutTradeNums());
        params.add("userid",StrUtil.equals(request.getType(),"huafei")? rechargeConfig.getUserid():rechargeConfig.getUserIdHY());
        params.add("sign", signature);

        try {
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
            HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers);
            log.info("requestEntity：{}", JSONObject.toJSONString(requestEntity));
            ResponseEntity<RevocationResp> response = restTemplate.exchange(rechargeConfig.getRevocationurl(), HttpMethod.POST, requestEntity, RevocationResp.class);
            log.info("第三方接口调用结束！response：{}", JSONObject.toJSONString(response));
            return response.getBody();
        } catch (Exception e) {
            log.error("调用第三方出错：{}", e.getMessage());
            throw new RuntimeException(e);
        }
    }

    /**
     * 查询订单状态
     * @return
     */
    @Override
    public RechargeQueryResp query(RechargeQueryReq request) {
        Map<String, Object> map = new HashMap<>();
        map.put("userid", StrUtil.equals(request.getType(),"huafei")? rechargeConfig.getUserid():rechargeConfig.getUserIdHY());
        map.put("out_trade_nums", request.getOutTradeNums());

        String signature = createSignature(map,rechargeConfig.getApikey().replace("T",""));
        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
        params.add("userid",StrUtil.equals(request.getType(),"huafei")? rechargeConfig.getUserid():rechargeConfig.getUserIdHY());
        params.add("out_trade_nums", request.getOutTradeNums());
        params.add("sign", signature);

        try {
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
            HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers);
            log.info("requestEntity：{}", JSONObject.toJSONString(requestEntity));
            ResponseEntity<RechargeQueryResp> response = restTemplate.exchange(rechargeConfig.getQueryurl(), HttpMethod.POST, requestEntity, RechargeQueryResp.class);
            log.info("第三方接口调用结束！response：{}", JSONObject.toJSONString(response));
            return response.getBody();
        } catch (Exception e) {
            log.error("调用第三方出错：{}", e.getMessage());
            throw new RuntimeException(e);
        }
    }

    @Override
    public RechargeQueryResp queryProduct(String type) {
        Map<String, Object> map = new HashMap<>();
//        map.put("userid", StrUtil.equals(type,"huafei")? rechargeConfig.getUserid():rechargeConfig.getUserIdHY());
        map.put("userid",305);

        String signature = createSignature(map,rechargeConfig.getApikey());
        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
//        params.add("userid",StrUtil.equals(type,"huafei")? rechargeConfig.getUserid():rechargeConfig.getUserIdHY());
        params.add("userid",305);
        params.add("sign", signature);

        try {
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
            HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers);
            log.info("requestEntity：{}", JSONObject.toJSONString(requestEntity));
            ResponseEntity<RechargeQueryResp> response = restTemplate.exchange("https://cz.9zhehuafei.cn/yrapi.php/index/elecity", HttpMethod.POST, requestEntity, RechargeQueryResp.class);
            log.info("第三方接口调用结束！response：{}", JSONObject.toJSONString(response));
            return response.getBody();
        } catch (Exception e) {
            log.error("调用第三方出错：{}", e.getMessage());
            throw new RuntimeException(e);
        }
    }


    /**
     * 生成签名
     * @param map
     * @return
     */
    public String createSignature(Map<String, Object> map,String apiKey) {
        List<Map.Entry<String, Object>> entries = new ArrayList<>(map.entrySet());
        Collections.sort(entries, new Comparator<Map.Entry<String, Object>>() {
            @Override
            public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) {
                return (o1.getKey().compareTo(o2.getKey()));
            }
        });

        log.info("排序后的List：{}", entries);
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, Object> entry : entries) {
            String key = entry.getKey();
            Object value = entry.getValue();
            sb.append(key).append("=").append(value).append("&");
        }
        sb.append("apikey").append("=").append(apiKey);
        log.info("排序后，未进行MD5加密的签名：{}", sb.toString().toUpperCase());
        return DigestUtil.md5Hex(sb.toString()).toUpperCase();
    }
}
